home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- Quick starter, ©1999 Dietmar Eilert.
-
- This is the C source code of the quickstarter. It demonstrates how to address
- the editor from other applications.
-
- DICE (important: compile as resident/pure program !):
-
- dcc ed.c rawdofmt.asm -// -proto -mRR -mi -pr -3.0 -o ed
-
- ------------------------------------------------------------------------------
- */
-
- /// "compiler"
-
- #ifdef __SASC
-
- #define __USE_SYSBASE
- #define __geta4 __saveds
- #define __stkargs __stdargs
-
- #define __A0 register __a0
- #define __A1 register __a1
- #define __A2 register __a2
- #define __A3 register __a3
- #define __A4 register __a4
- #define __A5 register __a5
- #define __A6 register __a6
- #define __A7 register __a7
- #define __D0 register __d0
- #define __D1 register __d1
- #define __D2 register __d2
- #define __D3 register __d3
- #define __D4 register __d4
- #define __D5 register __d5
- #define __D6 register __d6
- #define __D7 register __d7
-
- #endif
-
- #ifdef _DCC
-
- #define __asm
-
- #endif
-
- ///
- /// "includes"
-
- #include <exec/exec.h>
- #include <string.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <intuition/intuition.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/rdargs.h>
- #include <dos/dostags.h>
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
- #include <rexx/errors.h>
- #include <rexx/rxslib.h>
-
- // prototypes
-
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/icon_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/rexxsyslib_protos.h>
- #include <clib/utility_protos.h>
- #include <clib/wb_protos.h>
-
- // pragmas
-
- #ifdef __SASC
-
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/exec_sysbase_pragmas.h>
- #include <pragmas/icon_pragmas.h>
- #include <pragmas/intuition_pragmas.h>
- #include <pragmas/rexxsyslib_pragmas.h>
- #include <pragmas/utility_pragmas.h>
- #include <pragmas/wb_pragmas.h>
-
- #endif
-
- ///
- /// "defines"
-
- #define Prototype extern
- #define MAX_PATHLEN 512
- #define MAX_CMDLEN 256
- #define ARGBUFFER_SIZE 8192
- #define ARGBUFFER_LIMIT 8000
-
- ///
- /// "globals"
-
- extern struct Library *IconBase;
- extern struct Library *UtilityBase;
- extern struct Library *RexxSysBase;
- extern struct Library *DOSBase;
- extern struct Library *SysBase;
-
- ///
- /// "prototypes"
-
- Prototype int Action (UBYTE *, UBYTE *, BOOL, BOOL, ULONG *, UBYTE *, UBYTE *);
- Prototype UBYTE *LookForEditor (UBYTE *);
- Prototype int main (ULONG, UBYTE **);
- Prototype __stkargs UBYTE *myrawdofmt (UBYTE *, UBYTE *, APTR);
- Prototype __stkargs UBYTE *mysprintf (UBYTE *, UBYTE *, ...);
- Prototype LONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *, LONG *);
- Prototype UBYTE *StartEditor (UBYTE *, BOOL, UBYTE *, UBYTE *, UBYTE *);
- Prototype int wbmain (struct WBStartup *);
-
- ///
- /// "globals"
-
- #ifdef __SASC
-
- UBYTE Version[] = "$VER: ed 3.9 " __AMIGADATE__ "\n\0";
-
- #endif
-
- #ifdef _DCC
-
- UBYTE Version[] = "$VER: ed 3.9 (" __COMMODORE_DATE__ ")\n\0";
-
- #endif
-
- ///
- /// "entry points"
-
- /* --------------------------------------- main --------------------------------
-
- CLI entry point. Parse command line - create a string <argBuffer> containing
- provided file names (file names are made absolute). This string has to be
- FreeVec()'ed later on. Additionally, command line options are checked.
-
- */
-
- int
- main(argc, argv)
-
- ULONG argc;
- UBYTE *argv[];
- {
- int error;
-
- if (argc == 0) {
-
- error = wbmain((struct WBStartup *)argv);
- }
- else {
-
- UBYTE *argBuffer;
-
- error = 0;
-
- if (argBuffer = (UBYTE *)AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- struct RDArgs *rdArgs;
-
- LONG args[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- if (rdArgs = ReadArgs("FILETYPE/K,Y=STICKY/S,F=FILE/M,HIDE/S,-STICKY/S,L=LINE/N,A=AREXX/K,SESSION/K", args, NULL)) {
-
- if (args[2]) { // FILE/M
-
- UBYTE *path;
-
- if (path = (UBYTE *)AllocVec(MAX_PATHLEN, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- UBYTE **nextFile;
- BPTR lock;
-
- for (nextFile = (UBYTE **)args[2]; nextFile && *nextFile; ++nextFile) {
-
- strcpy(path, *nextFile);
-
- // expand file name
-
- if (lock = Lock(path, ACCESS_READ)) {
-
- NameFromLock(lock, path, MAX_PATHLEN);
-
- UnLock(lock);
- }
- else if (strchr(path, ':') == NULL) {
-
- GetCurrentDirName(path, MAX_PATHLEN);
-
- AddPart(path, *nextFile, MAX_PATHLEN);
- }
-
- strcat(argBuffer, "\42");
-
- strcat(argBuffer, path);
-
- strcat(argBuffer, "\42 ");
-
- // too many files ?
-
- if (strlen(argBuffer) > ARGBUFFER_LIMIT) {
-
- error = 5;
-
- break;
- }
- }
-
- FreeVec(path);
- }
- }
-
- if (error == 0)
-
- error = Action(argBuffer, (UBYTE *)args[0], args[1] || args[4], (BOOL)args[3], (ULONG *)args[5], (UBYTE *)args[6], (UBYTE *)args[7]);
-
- FreeArgs(rdArgs);
- }
- else
- error = 20;
-
- FreeVec(argBuffer);
- }
- else
- error = 20;
- }
-
- return(error);
- }
-
-
- /* ------------------------------------ wbmain ---------------------------------
-
- Workbench entry point. Read tooltypes of text icon(s) to decide whether user
- prefers a special configuration.
-
- */
-
- int
- wbmain(wbs)
-
- struct WBStartup *wbs;
- {
- int error;
- UBYTE *argBuffer;
-
- if (argBuffer = (UBYTE *)AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- struct DiskObject *diskObject = NULL;
-
- UBYTE *filetype;
- UBYTE *arexx;
- UBYTE *session;
- BOOL hide;
-
- error = 0;
-
- filetype = NULL;
- arexx = NULL;
- session = NULL;
-
- hide = FALSE;
-
- if (--wbs->sm_NumArgs) {
-
- UBYTE *path;
-
- if (path = (UBYTE *)AllocVec(MAX_PATHLEN, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- struct WBArg *wbArg = wbs->sm_ArgList;
-
- while ((wbs->sm_NumArgs)--) {
-
- ++wbArg;
-
- NameFromLock(wbArg->wa_Lock, path, MAX_PATHLEN);
-
- AddPart(path, wbArg->wa_Name, MAX_PATHLEN);
-
- // options not yet read ?
-
- if (diskObject == NULL) {
-
- if (diskObject = GetDiskObject(path)) {
-
- filetype = FindToolType(diskObject->do_ToolTypes, "FILETYPE");
- arexx = FindToolType(diskObject->do_ToolTypes, "AREXX" );
- session = FindToolType(diskObject->do_ToolTypes, "SESSION" );
-
- if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
-
- hide = TRUE;
- }
- }
-
- strcat(argBuffer, "\42");
-
- strcat(argBuffer, path);
-
- strcat(argBuffer, "\42 ");
-
- // too many files ?
-
- if (strlen(argBuffer) > ARGBUFFER_LIMIT) {
-
- error = 5;
-
- break;
- }
- }
-
- FreeVec(path);
- }
- else
- error = 20;
- }
-
- if (error == 0)
-
- error = Action(argBuffer, filetype, FALSE, hide, NULL, arexx, session);
-
- if (diskObject)
-
- FreeDiskObject(diskObject);
-
- FreeVec(argBuffer);
- }
- else
- error = 20;
-
- return(error);
- }
-
- ///
- /// "main routine"
-
- /* ------------------------------------ Action ---------------------------------
-
- Run editor if no running instance is found (note: running the editor will
- open a first window, i.e. no need to open a further one unless files are
- specified). Send LOCK message to running editor. Wait for positive reply,
- pass our list of <files> to that editor, unlock editor (use delayed unlock
- if <sticky> is specified). Files are passed to the editor as startup options
- if STICKY is not specified and if there is no running editor instance.
-
- */
-
- int
- Action(files, filetype, sticky, hide, line, arexx, session)
-
- UBYTE *files, *filetype, *arexx, *session;
- ULONG *line;
- BOOL hide, sticky;
- {
- int error;
- UBYTE *buffer;
-
- error = 0;
-
- if (buffer = (UBYTE *)AllocVec(MAX_PATHLEN, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- UBYTE *host;
- LONG result;
-
- if (host = LookForEditor(arexx)) { // editor found ?
-
- struct MsgPort *replyPort;
-
- if (replyPort = CreateMsgPort()) {
-
- if (session) {
-
- mysprintf(buffer, "SESSION LOAD CONFIG=\42%s\42", session);
-
- SendRexxCommand(host, buffer, replyPort, &result);
- }
- else if (*files) {
-
- if (SendRexxCommand(host, "LOCK CURRENT RELEASE=4", replyPort, &result)) {
-
- if (result == RC_OK) {
-
- if (*files) {
-
- strins(files, "NAME ");
-
- if (filetype) {
-
- mysprintf(buffer, "FILETYPE=\42%s\42 ", filetype);
-
- strins(files, buffer);
- }
-
- strins(files, "OPEN SMART QUIET ");
- }
- else
- strcpy(files, "MORE SMART");
-
- SendRexxCommand(host, files, replyPort, &result);
-
- if (line) {
-
- mysprintf(buffer, "GOTO LINE=%ld UNFOLD=TRUE", *(ULONG *)line);
-
- SendRexxCommand(host, buffer, replyPort, &result);
- }
-
- SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK", replyPort, &result);
- }
- }
- else
- error = 20;
- }
- else {
-
- // editor might be iconified - send wake-up-command (any command will work)
-
- SendRexxCommand(host, "SCREEN FRONT", replyPort, &result);
- }
-
- DeleteMsgPort(replyPort);
- }
- else
- error = 20;
- }
- else if (host = StartEditor(arexx, hide, filetype, files, session)) {
-
- if (line) {
-
- struct MsgPort *replyPort;
-
- if (replyPort = CreateMsgPort()) {
-
- mysprintf(buffer, "GOTO LINE=%ld UNFOLD=TRUE", *(ULONG *)line);
-
- SendRexxCommand(host, buffer, replyPort, &result);
-
- DeleteMsgPort(replyPort);
- }
- else
- error = 20;
- }
-
- if (sticky) {
-
- struct MsgPort *replyPort;
-
- if (replyPort = CreateMsgPort()) {
-
- if (SendRexxCommand(host, "LOCK CURRENT RELEASE=4", replyPort, &result)) {
-
- SendRexxCommand(host, "UNLOCK STICKY", replyPort, &result);
- }
- else
- error = 20;
-
- DeleteMsgPort(replyPort);
- }
- else
- error = 20;
- }
- }
- else
- error = 20;
-
- FreeVec(buffer);
- }
- else
- error = 20;
-
- return(error);
- }
-
- ///
- /// "misc"
-
- /* ----------------------------------- mysprintf -------------------------------
-
- sprintf replacement
-
- */
-
- __stkargs UBYTE *
- mysprintf(UBYTE *buffer, UBYTE *template, ...)
- {
- myrawdofmt(buffer, template, (APTR)((ULONG)&template + sizeof(ULONG)));
-
- return(buffer);
- }
-
-
- /* -------------------------------- LookForEditor ------------------------------
-
- Look for running editor task.
-
- */
-
- UBYTE *
- LookForEditor(host)
-
- UBYTE *host;
- {
- UBYTE *name = NULL;
-
- Forbid();
-
- if (host && FindPort(host))
-
- name = host;
-
- else {
-
- const UBYTE *try[] = { "GOLDED.1", "GOLDED.2", "GOLDED.3", "GOLDED.4", "GOLDED.5", NULL };
-
- UBYTE **next;
-
- for (next = (UBYTE **)try; *next; ++next) {
-
- if (FindPort(*next)) {
-
- name = *next;
-
- break;
- }
- }
- }
-
- Permit();
-
- return(name);
- }
-
-
- /* ----------------------------------- StartEditor -----------------------------
-
- Launch a new editor task. Look for editor assign. Create assign if none is
- found (assign[] is set by the GoldED installer script). Return pointer to
- host name (or NULL).
-
- */
-
- UBYTE *
- StartEditor(rexxname, hide, filetype, files, session)
-
- UBYTE *rexxname;
- UBYTE *filetype;
- UBYTE *files;
- UBYTE *session;
- BOOL hide;
- {
- UBYTE *buffer;
- UBYTE *host;
-
- host = NULL;
-
- if (buffer = (UBYTE *)AllocVec(MAX_PATHLEN, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- UBYTE *command;
-
- if (command = (UBYTE *)AllocVec(MAX_CMDLEN, MEMF_PUBLIC | MEMF_CLEAR)) {
-
- struct MsgPort *port;
- struct Task *task;
- UBYTE *cmd;
- LONG stack;
-
- task = FindTask(NULL);
-
- // determine current stack size (used as default for running editor)
-
- stack = (ULONG)task->tc_SPUpper - (ULONG)task->tc_SPLower;
-
- if (stack < 8192) // minimum 8 KB
-
- stack = 8192;
- // maximum 128 KB
- if (stack > 131072)
-
- stack = 131072;
-
- if (session) {
-
- mysprintf(command, "SESSION=\42%s\42", session);
-
- cmd = command;
- }
- else if (files) {
-
- cmd = files;
- }
- else {
-
- cmd = command;
- }
-
- if (filetype) {
-
- mysprintf(buffer, "FILETYPE=\42%s\42 ", filetype);
-
- strins(cmd, buffer);
- }
-
- if (rexxname) {
-
- host = rexxname;
-
- mysprintf(buffer, "AREXX=\42%s\42 ", rexxname);
-
- strins(cmd, buffer);
- }
- else
- host = "GOLDED.1";
-
- if (hide)
-
- strins(cmd, "HIDE ");
-
- strins(cmd, "golded:golded ");
-
- port = NULL;
-
- if (SystemTags(cmd, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, NP_StackSize, stack, TAG_DONE) == 0) {
-
- UWORD try;
-
- for (try = 100; try--; Delay(10)) {
-
- Forbid();
-
- port = FindPort(host);
-
- Permit();
-
- if (port)
-
- break;
- }
- }
-
- if (port == NULL)
-
- host = NULL;
-
- FreeVec(command);
- }
-
- FreeVec(buffer);
- }
-
- return(host);
- }
-
- ///
- /// "rexx"
-
- /* ---------------------------------- SendRexxCommand -------------------------
-
- Send ARexx message & wait for answer. Return pointer to result or NULL.
-
- */
-
- LONG *
- SendRexxCommand(port, cmd, replyPort, result)
-
- struct MsgPort *replyPort;
- UBYTE *cmd;
- UBYTE *port;
- LONG *result;
- {
- struct MsgPort *rexxport;
-
- Forbid();
-
- if (rexxport = FindPort(port)) {
-
- struct RexxMsg *rexxMsg, *answer;
-
- if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
-
- if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
-
- rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
-
- PutMsg(rexxport, &rexxMsg->rm_Node);
-
- *result = 0;
-
- do {
-
- WaitPort(replyPort);
-
- if (answer = (struct RexxMsg *)GetMsg(replyPort))
-
- *result = answer->rm_Result1;
-
- } while (answer == NULL);
-
- Permit();
-
- if (answer->rm_Result1 == RC_OK)
-
- if (answer->rm_Result2)
-
- DeleteArgstring((UBYTE *)answer->rm_Result2);
-
- DeleteArgstring((UBYTE *)ARG0(answer));
-
- DeleteRexxMsg(answer);
-
- return(result);
- }
- else
- DeleteRexxMsg(rexxMsg);
- }
- }
-
- Permit();
-
- return(NULL);
- }
-
- ///
-